home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
embedded
/
68hc11
/
smallc11.arc
/
CC31.C
< prev
next >
Wrap
Text File
|
1988-05-27
|
9KB
|
356 lines
/*
** lval[0] - symbol table address, else 0 for constant
** lval[1] - type of indirect obj to fetch, else 0 for static
** lval[2] - type of pointer or array, else 0 for all other
** lval[3] - true if constant expression
** lval[4] - value of constant expression
** lval[5] - true if secondary register altered
** lval[6] - function address of highest/last binary operator
** lval[7] - stage address of "oper 0" code, else 0
*/
/*
** skim over terms adjoining || and && operators
*/
skim(opstr, testfunc, dropval, endval, heir, lval)
char *opstr;
int testfunc, dropval, endval, heir, lval[]; {
int k, hits, droplab, endlab;
hits=0;
while(1) {
k=plunge1(heir, lval);
if(nextop(opstr)) {
bump(opsize);
if(hits==0) {
hits=1;
droplab=getlabel();
}
dropout(k, testfunc, droplab, lval);
}
else if(hits) {
dropout(k, testfunc, droplab, lval);
const1(endval);
jump(endlab=getlabel());
postlabel(droplab);
const1(dropval);
postlabel(endlab);
lval[1]=lval[2]=lval[3]=lval[7]=0;
return 0;
}
else return k;
}
}
/*
** test for early dropout from || or && evaluations
*/
dropout(k, testfunc, exit1, lval) int k, (*testfunc)(), exit1, lval[]; {
if(k) rvalue(lval);
else if(lval[3]) const1(lval[4]);
(*testfunc)(exit1); /* jumps on false */
}
/*
** plunge to a lower level
*/
plunge(opstr, opoff, heir, lval)
char *opstr;
int opoff, heir, lval[]; {
int k, lval2[8];
k=plunge1(heir, lval);
if(nextop(opstr)==0) return k;
if(k) rvalue(lval);
while(1) {
if(nextop(opstr)) {
bump(opsize);
opindex=opindex+opoff;
plunge2(op[opindex], op2[opindex], heir, lval, lval2);
}
else return 0;
}
}
/*
** unary plunge to lower level
*/
plunge1(heir, lval) int (*heir)(), lval[]; {
char *before, *start;
int k;
setstage(&before, &start);
k=(*heir)(lval);
if(lval[3]) clearstage(before,0); /* load constant later */
return k;
}
/*
** binary plunge to lower level
*/
plunge2(oper, oper2, heir, lval, lval2)
int (*oper)(), (*oper2)(), (*heir)(), lval[], lval2[];
{
char *before, *start;
setstage(&before, &start);
lval[5]=1; /* flag secondary register used */
lval[7]=0; /* flag as not "... oper 0" syntax */
if(lval[3]) { /* constant on left side not yet loaded */
if(plunge1(heir, lval2)) rvalue(lval2);
if(lval[4]==0) lval[7]=stagenext;
const2(lval[4]<<dbltest(lval2, lval));
}
else { /* non-constant on left side */
push();
if(plunge1(heir, lval2)) rvalue(lval2);
if(lval2[3]) { /* constant on right side */
if(lval2[4]==0) lval[7]=start;
if(oper == op[ADD]) { /* may test other commutative operators */
csp=csp+2;
clearstage(before, 0);
const2(lval2[4]<<dbltest(lval, lval2)); /* load secondary */
}
else {
const1(lval2[4]<<dbltest(lval, lval2)); /* load primary */
smartpop(lval2, start);
}
}
else { /* non-constants on both sides */
smartpop(lval2, start);
if((oper == op[ADD])|(oper == op[SUB])) {
if(dbltest(lval,lval2)) doublereg();
if(dbltest(lval2,lval)) {
swap();
doublereg();
if(oper == op[SUB]) swap();
}
}
}
}
if(oper) {
if(lval[3]=lval[3]&lval2[3]) {
lval[4]=calc(lval[4], oper, lval2[4]);
clearstage(before, 0);
lval[5]=0;
}
else {
if((lval[2]==0)&(lval2[2]==0)) {
(*oper)();
lval[6]=oper; /* identify the operator */
}
else {
(*oper2)();
lval[6]=oper2; /* identify the operator */
}
}
if(oper == op[SUB]) {
if((lval[2]==CINT)&(lval2[2]==CINT)) {
swap();
const1(1);
asr(); /** div by 2 **/
}
}
if((oper == op[SUB])|(oper == op[ADD])) result(lval, lval2);
}
}
calc(left, oper, right) int left, oper, right; {
if(oper == op[OR]) return (left | right);
else if(oper == op[XOR]) return (left ^ right);
else if(oper == op[AND]) return (left & right);
else if(oper == op[EQ]) return (left == right);
else if(oper == op[NE]) return (left != right);
else if(oper == op[LE]) return (left <= right);
else if(oper == op[GE]) return (left >= right);
else if(oper == op[LT]) return (left < right);
else if(oper == op[GT]) return (left > right);
else if(oper == op[ASR]) return (left >> right);
else if(oper == op[ASL]) return (left << right);
else if(oper == op[ADD]) return (left + right);
else if(oper == op[SUB]) return (left - right);
else if(oper ==op[MULT]) return (left * right);
else if(oper == op[DIV]) return (left / right);
else if(oper == op[MOD]) return (left % right);
else return 0;
}
expression(const1, val) int *const1, *val; {
int lval[8];
if(heir1(lval)) rvalue(lval);
if(lval[3]) {
*const1=1;
*val=lval[4];
}
else *const1=0;
}
heir13(lval) int lval[]; {
int k,inc(),dec();
char *ptr;
if(match("++")) { /* ++lval */
if(heir13(lval)==0) {
needlval();
return 0;
}
step(inc, lval);
return 0;
}
else if(match("--")) { /* --lval */
if(heir13(lval)==0) {
needlval();
return 0;
}
step(dec, lval);
return 0;
}
else if (match("~")) { /* ~ */
if(heir13(lval)) rvalue(lval);
com();
#ifdef PHASE2
lval[4] = ~lval[4];
#endif
return 0;
}
else if (match("!")) { /* ! */
if(heir13(lval)) rvalue(lval);
lneg();
#ifdef PHASE2
lval[4] = !lval[4];
#endif
return 0;
}
else if (match("-")) { /* unary - */
if(heir13(lval)) rvalue(lval);
neg();
lval[4] = -lval[4];
return 0;
}
else if(match("*")) { /* unary * */
if(heir13(lval)) rvalue(lval);
if(ptr=lval[0])lval[1]=ptr[TYPE];
else lval[1]=CINT;
lval[2]=0; /* flag as not pointer or array */
lval[3]=0; /* flag as not constant */
return 1;
}
else if(match("&")) { /* unary & */
if(heir13(lval)==0) {
error("illegal address");
return 0;
}
ptr=lval[0];
lval[2]=ptr[TYPE];
if(lval[1]) return 0;
/* global & non-array */
address(ptr);
lval[1]=ptr[TYPE];
return 0;
}
else {
k=heir14(lval);
if(match("++")) { /* lval++ */
if(k==0) {
needlval();
return 0;
}
step(inc, lval);
dec(lval[2]>>2);
return 0;
}
else if(match("--")) { /* lval-- */
if(k==0) {
needlval();
return 0;
}
step(dec, lval);
inc(lval[2]>>2);
return 0;
}
else return k;
}
}
heir12(lval) int lval[]; {
return plunge("* / %", 13, heir13, lval);
}
heir11(lval) int lval[]; {
return plunge("+ -", 11, heir12, lval);
}
heir10(lval) int lval[]; {
return plunge(">> <<", 9, heir11, lval);
}
heir9(lval) int lval[]; {
return plunge("<= >= < >", 5, heir10, lval);
}
heir8(lval) int lval[]; {
return plunge("== !=", 3, heir9, lval);
}
heir7(lval) int lval[]; {
return plunge("&", 2, heir8, lval);
}
heir6(lval) int lval[]; {
return plunge("^", 1, heir7, lval);
}
heir5(lval) int lval[]; {
return plunge("|", 0, heir6, lval);
}
heir4(lval) int lval[]; {
int hier5(),ne0();
return skim("&&", ne0, 0, 1, heir5, lval);
}
heir3(lval) int lval[]; {
int hier4(),eq0();
return skim("||", eq0, 1, 0, heir4, lval);
}
heir1(lval) int lval[]; {
int k,lval2[8], oper;
k=plunge1(heir3, lval);
if(lval[3]) const1(lval[4]);
if(match("|=")) oper=or;
else if(match("^=")) oper=xor;
else if(match("&=")) oper=and;
else if(match("+=")) oper=add;
else if(match("-=")) oper=sub;
else if(match("*=")) oper=mult;
else if(match("/=")) oper=div;
else if(match("%=")) oper=mod;
else if(match(">>=")) oper=asr;
else if(match("<<=")) oper=asl;
else if(match("=")) oper=0;
else return k;
if(k==0) {
needlval();
return 0;
}
if(lval[1]) {
if(oper) {
push();
rvalue(lval);
}
plunge2(oper, oper, heir1, lval, lval2);
if(oper) pop();
}
else {
if(oper) {
rvalue(lval);
plunge2(oper, oper, heir1, lval, lval2);
}
else {
if(heir1(lval2)) rvalue(lval2);
lval[5]=lval2[5];
}
}
store(lval);
return 0;
}